ant-design-pro 动态菜单配置

Ant Design Pro 路由及菜单解析

我们先看下官网关于路由和菜单的介绍

路由和菜单是组织起一个应用的关键骨架,pro 中的路由为了方便管理,使用了中心化的方式,在 router.config.js 统一配置和管理。

整个路由和菜单的基本结构如官网所述:

路由管理 通过约定的语法根据在 router.config.js 中配置路由。

菜单生成 根据路由配置来生成菜单。菜单项名称,嵌套路径与路由高度耦合。

面包屑 组件 PageHeader 中内置的面包屑也可由脚手架提供的配置信息自动生成。

路由

目前脚手架中所有的路由都通过 router.config.js 来统一管理,在 umi 的配置中我们增加了一些参数,如 name,icon,hideChildrenInMenu,authority,来辅助生成菜单

菜单

菜单根据 router.config.js 生成,具体逻辑在 src/layouts/BasicLayout 中的 formatter 方法实现

动态菜单

看过Ant Design Pro 2.0的盆友应该知道,整个页面路由的配置都写在文件router.config.js中了,由于是提前配置再加载,所以它是静态的

但往往在我们的实际项目中,都存在需要动态配置路由的情况,比如题主最近在公司做的内部系统项目,就需要针对不同管理权限的人提供不同的菜单路由

在讲解动态菜单生成的具体步骤前,我们先来看下官网对于生成动态菜单方法的介绍

如果你的项目并不需要菜单,你可以直接在 BasicLayout 中删除 SiderMenu 组件的挂载。并在 src/layouts/BasicLayout 中 设置 const MenuData = []。

如果你需要从服务器请求菜单,可以将 menuData 设置为 state,然后通过网络获取来修改了 state。

这句话到底是什么意思了?接下来跟着具体的实例操作一遍,相信大家就明白了

实例介绍

  1. config/router.config.js中配置所有页面需要的路由参数

  2. src/layouts/BasicLayout.js中连接model与menuData数据

export default connect(({ menuTree, loading, global, setting }) => ({
  menuTree, // +
  loading: loading.effects['menuTree/getMenu'], // +
  collapsed: global.collapsed,
  layout: setting.layout,
  ...setting,
}))(BasicLayout);

请求model中的menuData数据

componentDidMount() {
  const { dispatch } = this.props;
  // +
  dispatch({
    type: 'menuTree/getMenu'
  })
  dispatch({
    type: 'user/fetchCurrent',
  });
  dispatch({
    type: 'setting/getSetting',
  })

在获取面包屑映射的时候配置states数据

getBreadcrumbNameMap() {
  const routerMap = {};
  const mergeMenuAndRouter = data => {
    data.forEach(menuItem => {
      if (menuItem.children) {
        mergeMenuAndRouter(menuItem.children);
      }
      // Reduce memory usage
      routerMap[menuItem.path] = menuItem;
    });
  };
  // +
  const {menuTree} = this.props
  const {menuData} = menuTree
  mergeMenuAndRouter(formatter(menuData));
  return routerMap;
}

在render中获取到menuData的数据

render() {
  const {
    menuTree, // +
    navTheme,
    layout: PropsLayout,
    children,
    location: { pathname },
  } = this.props;
  // +
  const { isMobile } = this.state;
  const {menuData} = menuTree
  const menuList = formatter(menuData)
  const isTop = PropsLayout === 'topmenu';

  const layout = (
    <Layout>
      {isTop && !isMobile ? null : (
        <SiderMenu
          logo={logo}
          Authorized={Authorized}
          theme={navTheme}
          onCollapse={this.handleMenuCollapse}
          menuData = {menuList} // +
          isMobile={isMobile}
          {...this.props}
        />
      )}
      <Layout
        style={{
          ...this.getLayoutStyle(),
          minHeight: '100vh',
        }}
      >
        <Header
          menuData={menuList} // +
          // ......
  1. src/models/menuTree.js中更新menuData数据
import { queryMenu } from '@/services/menuTree';
 
export default {
  namespace: 'menuTree',
 
  state: {
    menuData: [],
  },
 
  effects: {
    *getMenu(_, { call, put }) {
      const response = yield call(queryMenu);
      console.log('response',response)
      yield put({
        type: 'menuResult',
        payload: response[2].routes,
      });
    },
  },
 
  reducers: {
    menuResult(state, action) {
      return {
        ...state,
        menuData: action.payload,
      };
    },
  },
};
  1. src/services/menuTree.js中请求menuData数据
import request from '@/utils/request';
 
export async function queryMenu() {
  return request('/menu/getMenuTree');
}
  1. 我们使用mock数据来模拟请求的路由参数,在mock/menu.js中配置所需要显示的动态路由
export default {
  'GET /menu/getMenuTree':[
    // user
    {
      path: '/user',
      component: '../layouts/UserLayout',
      routes: [
        { path: '/user', redirect: '/user/login' },
        { path: '/user/login', component: './User/Login' },
        { path: '/user/register', component: './User/Register' },
        { path: '/user/register-result', component: './User/RegisterResult' },
      ],
    },
    // ......
  1. src/locales/zh-CN.jssrc/locales/en-US.js中配置相应路由的显示名称

以上就是Ant Design Pro 动态菜单的所有步骤了